package org.cybzacg.encryption.model;

import org.cybzacg.encryption.context.EncryptionContext;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Objects;

/**
 * 验证结果类
 * 封装验证操作的结果信息
 * 
 * @author encryption team
 * @version 1.0
 */
public class ValidationResult {
    
    private final boolean valid;
    private final String message;
    private final List<String> warnings;
    private final List<String> errors;
    private final LocalDateTime timestamp;
    private final Map<String, Object> details;
    private final EncryptionContext context;
    
    private ValidationResult(Builder builder) {
        this.valid = builder.valid;
        this.message = builder.message;
        this.warnings = new ArrayList<>(builder.warnings);
        this.errors = new ArrayList<>(builder.errors);
        this.timestamp = builder.timestamp;
        this.details = new HashMap<>(builder.details);
        this.context = builder.context;
    }
    
    /**
     * 获取验证结果
     * 
     * @return 是否有效
     */
    public boolean isValid() {
        return valid;
    }
    
    /**
     * 获取验证消息
     * 
     * @return 验证消息
     */
    public String getMessage() {
        return message;
    }
    
    /**
     * 获取警告列表
     * 
     * @return 警告列表的副本
     */
    public List<String> getWarnings() {
        return new ArrayList<>(warnings);
    }
    
    /**
     * 获取错误列表
     * 
     * @return 错误列表的副本
     */
    public List<String> getErrors() {
        return new ArrayList<>(errors);
    }
    
    /**
     * 获取时间戳
     * 
     * @return 时间戳
     */
    public LocalDateTime getTimestamp() {
        return timestamp;
    }
    
    /**
     * 获取详细信息
     * 
     * @return 详细信息映射的副本
     */
    public Map<String, Object> getDetails() {
        return new HashMap<>(details);
    }
    
    /**
     * 获取上下文
     * 
     * @return 上下文
     */
    public EncryptionContext getContext() {
        return context;
    }
    
    /**
     * 检查是否有警告
     * 
     * @return 是否有警告
     */
    public boolean hasWarnings() {
        return !warnings.isEmpty();
    }
    
    /**
     * 检查是否有错误
     * 
     * @return 是否有错误
     */
    public boolean hasErrors() {
        return !errors.isEmpty();
    }
    
    /**
     * 获取警告数量
     * 
     * @return 警告数量
     */
    public int getWarningCount() {
        return warnings.size();
    }
    
    /**
     * 获取错误数量
     * 
     * @return 错误数量
     */
    public int getErrorCount() {
        return errors.size();
    }
    
    /**
     * 获取详细信息值
     * 
     * @param key 键
     * @return 值，可能为null
     */
    public Object getDetail(String key) {
        return details.get(key);
    }
    
    /**
     * 创建成功的验证结果
     * 
     * @param message 验证消息
     * @param context 上下文
     * @return 验证结果
     */
    public static ValidationResult success(String message, EncryptionContext context) {
        return new Builder()
                .valid(true)
                .message(message)
                .context(context)
                .build();
    }
    
    /**
     * 创建失败的验证结果
     * 
     * @param message 验证消息
     * @param errors 错误列表
     * @param context 上下文
     * @return 验证结果
     */
    public static ValidationResult failure(String message, List<String> errors, EncryptionContext context) {
        return new Builder()
                .valid(false)
                .message(message)
                .errors(errors)
                .context(context)
                .build();
    }
    
    /**
     * 创建失败的验证结果
     * 
     * @param message 验证消息
     * @param error 错误信息
     * @param context 上下文
     * @return 验证结果
     */
    public static ValidationResult failure(String message, String error, EncryptionContext context) {
        List<String> errors = new ArrayList<>();
        errors.add(error);
        return failure(message, errors, context);
    }
    
    /**
     * 创建带有警告的验证结果
     * 
     * @param message 验证消息
     * @param warnings 警告列表
     * @param context 上下文
     * @return 验证结果
     */
    public static ValidationResult withWarnings(String message, List<String> warnings, EncryptionContext context) {
        return new Builder()
                .valid(true)
                .message(message)
                .warnings(warnings)
                .context(context)
                .build();
    }
    
    /**
     * 创建带有警告的验证结果
     * 
     * @param message 验证消息
     * @param warning 警告信息
     * @param context 上下文
     * @return 验证结果
     */
    public static ValidationResult withWarning(String message, String warning, EncryptionContext context) {
        List<String> warnings = new ArrayList<>();
        warnings.add(warning);
        return withWarnings(message, warnings, context);
    }
    
    /**
     * 建造者类
     */
    public static class Builder {
        private boolean valid = true;
        private String message;
        private List<String> warnings = new ArrayList<>();
        private List<String> errors = new ArrayList<>();
        private LocalDateTime timestamp = LocalDateTime.now();
        private Map<String, Object> details = new HashMap<>();
        private EncryptionContext context;
        
        public Builder valid(boolean valid) {
            this.valid = valid;
            return this;
        }
        
        public Builder message(String message) {
            this.message = message;
            return this;
        }
        
        public Builder warning(String warning) {
            this.warnings.add(warning);
            return this;
        }
        
        public Builder warnings(List<String> warnings) {
            this.warnings = new ArrayList<>(warnings);
            return this;
        }
        
        public Builder error(String error) {
            this.errors.add(error);
            return this;
        }
        
        public Builder errors(List<String> errors) {
            this.errors = new ArrayList<>(errors);
            return this;
        }
        
        public Builder timestamp(LocalDateTime timestamp) {
            this.timestamp = timestamp;
            return this;
        }
        
        public Builder detail(String key, Object value) {
            this.details.put(key, value);
            return this;
        }
        
        public Builder details(Map<String, Object> details) {
            this.details = new HashMap<>(details);
            return this;
        }
        
        public Builder context(EncryptionContext context) {
            this.context = context;
            return this;
        }
        
        public ValidationResult build() {
            return new ValidationResult(this);
        }
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ValidationResult that = (ValidationResult) o;
        return valid == that.valid &&
                Objects.equals(message, that.message) &&
                Objects.equals(warnings, that.warnings) &&
                Objects.equals(errors, that.errors) &&
                Objects.equals(timestamp, that.timestamp) &&
                Objects.equals(details, that.details);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(valid, message, warnings, errors, timestamp, details);
    }
    
    @Override
    public String toString() {
        return "ValidationResult{" +
                "valid=" + valid +
                ", message='" + message + '\'' +
                ", warningCount=" + getWarningCount() +
                ", errorCount=" + getErrorCount() +
                ", timestamp=" + timestamp +
                '}';
    }
}
